<template>
  <div class="tool-tip">
    <slot></slot>
  </div>
</template>
<script>
import Vue from 'vue';
import PopperJS from './popper';
import debounce from 'throttle-debounce/debounce';

export default {
  props: {
    effect: {
      type: String,
      default: 'dark'
    },
    placement: {
      type: String,
      default: 'bottom'
    },
    popperClass: String,
    content: String,
    popperOptions: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  data() {
    return {
      showPoper: false,
      popperJS: null,
      currentPlacement: ''
    };
  },
  watch: {
    showPoper(val) {
      this.createPopperDom();
      val ? this.updatePopper() : '';
    }
  },
  beforeCreate() {
    this.popperVM = new Vue({
      data: function() {
        return {
          node: ''
        };
      },
      render() {
        return this.node;
      }
    }).$mount();
    this.debounceClose = debounce(200, () => this.handleClosePoper());
  },
  mounted() {
    this.refrence = this.$el;
    this.refrence.onmouseenter = this.show;
    this.refrence.onmouseleave = this.hide;
    this.createPopperDom();
  },
  methods: {
    createPopperDom() {
      this.popperVM.node = (
        <transition name="fade">
          <div
            ref="popper"
            v-show={this.showPoper}
            class={['tooltip__popper', 'is-' + this.effect, this.popperClass]}
            onMouseleave={() => {
              this.setExpectState(false);
              this.debounceClose();
            }}
            onMouseenter={() => {
              this.setExpectState(true);
            }}
          >
            {this.$slots.content || this.content}
          </div>
        </transition>
      );
      console.log(this.popperVM, '22');
    },
    show() {
      this.expectState = true;
      this.handleShowPoper();
    },
    hide() {
      this.expectState = false;
      this.debounceClose();
    },
    handleShowPoper() {
      this.showPoper = true;
    },
    handleClosePoper() {
      if (this.expectState) return;
      this.showPoper = false;
    },
    createPoper() {
      this.currentPlacement = this.currentPlacement || this.placement;
      if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.currentPlacement)) {
        return;
      }
      let refrence = this.refrence;
      let popper = this.$refs.popper;
      this.appendArrow(popper);
      const options = this.popperOptions;
      options.placement = this.currentPlacement;
      if (popper) document.body.appendChild(popper);
      this.popperJS = new PopperJS(refrence, popper, options);
      this.popperJS.onCreate(_ => {
        this.$nextTick(this.updatePopper);
      });
    },
    updatePopper() {
      if (this.popperJS) {
        // 第二次进入的话更新弹框 说明弹框节点已经存在
        this.popperJS.update();
      } else {
        // 首次进入 建立弹框dom
        this.createPoper();
      }
    },
    destroyPopper() {
      this.popperJS.destroy();
      this.popperJS = null;
    },
    setExpectState(expectState) {
      this.expectState = expectState;
    },
    appendArrow(element) {
      let hash;
      if (this.appended) {
        return;
      }

      this.appended = true;

      for (let item in element.attributes) {
        if (/^_v-/.test(element.attributes[item].name)) {
          hash = element.attributes[item].name;
          break;
        }
      }
      const arrow = document.createElement('div');
      if (hash) {
        arrow.setAttribute(hash, '');
      }
      arrow.setAttribute('x-arrow', '');
      arrow.className = 'jq_popper__arrow';
      element.appendChild(arrow);
    }
  }
};
</script>
<style lang="scss">
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
.tooltip__popper {
  position: absolute;
  border-radius: 4px;
  padding: 10px;
  border: 1px solid #ccc;
  font-size: 12px;
  color: #fff;
  word-wrap: break-word;
  background-color: #303133;
  .jq_popper__arrow {
    border: 6px solid transparent;
    width: 0;
    height: 0;
    position: absolute;
  }
  &[x-placement^='top'] {
    margin-bottom: 12px;
    .jq_popper__arrow {
      bottom: -5px;
      border-top-color: #303133;
      border-bottom-width: 0;
    }
  }
  &[x-placement^='bottom'] {
    margin-top: 12px;
    .jq_popper__arrow {
      top: -5px;
      border-bottom-color: #303133;
      border-top-width: 0;
    }
  }
  &[x-placement^='left'] {
    margin-right: 12px;
    .jq_popper__arrow {
      right: -5px;
      border-left-color: #303133;
      border-right-width: 0;
    }
  }
  &[x-placement^='right'] {
    margin-left: 12px;
    .jq_popper__arrow {
      left: -5px;
      border-right-color: #303133;
      border-left-width: 0;
    }
  }
}
</style>
